package ldk.util.adapterwrappers;

import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * 显示加载更多
 * Created by ldkxingzhe@163.com on 2017/5/16.
 */
public class LoadMoreAdapterWrapper extends RecyclerView.Adapter{
    @SuppressWarnings("unused")
    private static final String TAG = "LoadMoreAdapterWrapper";

    @NonNull
    private final RecyclerView.Adapter mRealAdapter;
    private RecyclerView.ViewHolder mLoadMoreViewHolder;
    private boolean mIsRefreshing = false;
    private boolean mIsEndRefresh = false;
    private boolean mIsLoadMoreInEnd = true;
    private boolean mIsEndByException = false;

    private LoadMoreListener mListener;
    private Handler mHandler;

    public interface LoadMoreListener{
        void onLoadMore();
    }

    public void setIsLoadMoreInEnd(boolean isLoadMoreInEnd){
        mIsLoadMoreInEnd = isLoadMoreInEnd;
        notifyDataSetChanged();
    }

    public void setLoadMoreListener(@Nullable LoadMoreListener listener){
        mListener = listener;
    }


    public LoadMoreAdapterWrapper(@NonNull RecyclerView.Adapter realAdapter) {
        this.mRealAdapter = realAdapter;
        realAdapter.registerAdapterDataObserver(mDataObserver);
        mHandler = new Handler();
    }

    public void setLoadMoreViewHolder(@Nullable RecyclerView.ViewHolder loadMoreViewHolder){
        mLoadMoreViewHolder = loadMoreViewHolder;
    }

    public RecyclerView.ViewHolder getLoadMoreViewHolder(){
        return mLoadMoreViewHolder;
    }

    public boolean isRefreshing(){
        return mIsRefreshing;
    }

    public void endByException(boolean isEndByException){
        mIsEndByException = isEndByException;
        if (mLoadMoreViewHolder instanceof LoadMoreViewHolder && mIsEndByException){
            ((LoadMoreViewHolder) mLoadMoreViewHolder).setState(LoadMoreViewHolder.NO_MORE);
        }
    }

    public void setRefreshing(boolean isRefreshing){
        mIsRefreshing = isRefreshing;
        if (mIsRefreshing){
            mIsEndByException = false;
        }
        notifyItemChanged(mIsLoadMoreInEnd ? getItemCount() - 1 : 0);
    }

    public void setIsEndRefresh(boolean endRefresh){
        mIsEndRefresh = endRefresh;
        if (mLoadMoreViewHolder instanceof LoadMoreViewHolder){
            ((LoadMoreViewHolder) mLoadMoreViewHolder).setState(
                    endRefresh ? LoadMoreViewHolder.NO_MORE : LoadMoreViewHolder.LOADING);
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == 0){
            if (mLoadMoreViewHolder == null){
                mLoadMoreViewHolder = new LoadMoreViewHolder(parent);
                setIsEndRefresh(mIsEndRefresh);
            }
            return  mLoadMoreViewHolder;
        }else{
            return mRealAdapter.onCreateViewHolder(parent, viewType - 1);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (!isPositionLoadMore(position)){
            mRealAdapter.onBindViewHolder(holder, mIsLoadMoreInEnd ? position : position - 1);
        }else{
            boolean invisible = position == 0 && mIsLoadMoreInEnd;
            if (holder instanceof LoadMoreViewHolder){
                holder.itemView.setVisibility(invisible ? View.INVISIBLE : View.VISIBLE);
            }
            if (mListener != null && !mIsRefreshing && !mIsEndRefresh && !mIsEndByException){
                mIsRefreshing = true;
                // fixed: 修复RecyclerView layout过程中与scroll状态的bug
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mListener.onLoadMore();
                    }
                });
            }
        }
    }

    @Override
    public int getItemCount() {
        int realItemCount = mRealAdapter.getItemCount();
        return realItemCount + 1;
    }

    private boolean isPositionLoadMore(int position) {
        return mIsLoadMoreInEnd ? position == mRealAdapter.getItemCount() : position == 0;
    }

    @Override
    public int getItemViewType(int position) {
        if (isPositionLoadMore(position)){
            return 0;
        }
        return mRealAdapter.getItemViewType(mIsLoadMoreInEnd ? position : position - 1) + 1;
    }

    private RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            notifyDataSetChanged();
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            if (mIsLoadMoreInEnd){
                notifyItemRangeChanged(positionStart, itemCount);
            }else{
                notifyItemRangeChanged(positionStart + 1, itemCount);
            }
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            notifyItemRangeChanged(mIsLoadMoreInEnd ? positionStart : positionStart + 1, itemCount, payload);
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            notifyItemRangeInserted(mIsLoadMoreInEnd ? positionStart : positionStart + 1, itemCount);
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            notifyItemRangeRemoved(mIsLoadMoreInEnd ? positionStart : positionStart + 1, itemCount);
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            onChanged();
        }
    };
}
